﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Googler.DAL;
using System.Data;
using HodhodNews.Storage;
using Googler.BLL;
using System.Web.Security;
using HodhodNews.Controllers;

namespace HodhodNews.Storage
{
    public class EntityFrameworkStorageProvider : StorageProvider
    {

        DataContext _DataContent;
        public DataContext DataContent
        {
            get
            {
                if (_DataContent == null)
                    _DataContent = new DataContext();
                return _DataContent;
            }
        }

        /// <summary>
        /// Save current News List to database
        /// </summary>
        public override void Save(List<News> list)
        {
            int savedNewsCount = 0;

            foreach (News atom in list)
            {

                bool created = this.Create(atom);
                if (created)
                {
                    savedNewsCount++;
                }

            }
            Sessions.NotificationMessages.Add(new NotificationMessage()
            {
                Text = "Saved News Count " + savedNewsCount,
                Ident = 1
            });
        }
        public override void UpdateStatistics()
        {
            var nextDate = DateTime.Now.AddDays(1).Date;
            var nowDate = DateTime.Now.Date;

            var keywords = this.DataContent.Keywords;
            foreach (var k in keywords)
            {
                var count = this.DataContent.NewsKeywords.Where(n => n.IsNewsDeleted == null || n.IsNewsDeleted == false)
                                                .Where(n => n.NewsModificationDate >= nowDate)
                                                .Where(n => n.NewsModificationDate <= nextDate)
                                                .Where(n => n.KeywordID == k.ID)
                                                .Count();

                k.NewsCount = count;

            }
            this.DataContent.SaveChanges();
        }
        public override bool Create(News entity)
        {

            //IDataAcessLayerBaseInterface DAL = DALHelper.GetDataAccessLayer();
            //DAL.OpenConnection();
            //int oid = (int)DAL.ExecuteScalar("News_Add",
            //     "OId", entity.OId,
            //     "EntryId", entity.EntryId,
            //     "Aggregator", entity.Aggregator,
            //     "IsDeleted", entity.IsDeleted,
            //     "IsExtracted", entity.IsExtracted,
            //     "LanguageID", entity.LanguageID,
            //     "Link", entity.Link,
            //     "ModificationDate", entity.ModificationDate,
            //     "NewsTime", entity.NewsTime,
            //     "PublishDate", entity.PublishDate,
            //     "Publisher", entity.Publisher,
            //     "Summary", entity.Summary,
            //     "SummaryHtml", entity.SummaryHtml,
            //     "Text", entity.Text,
            //     "Title", entity.Title
            //    );
            //DAL.CloseConnection();
            //entity.OId = oid;
            //return oid > 0;

            if (entity == null || string.IsNullOrWhiteSpace(entity.Link))
            {
                return false;
            }

            if (Sessions.AggregatedUrls.ContainsKey(entity.Link))
            {
                return false;
            }

            bool newsAggregatedBefore = this.DataContent.News.Where(n => n.Link == entity.Link).FirstOrDefault() != null;
            if (!newsAggregatedBefore)
            {
                this.DataContent.AddToNews(entity);
                this.DataContent.SaveChanges();
                this.DataContent.Detach(entity);

                if (!Sessions.AggregatedUrls.ContainsKey(entity.Link))
                {
                    Sessions.AggregatedUrls.Add(entity.Link, DateTime.Now);
                }
                foreach (var keyword in entity.Keywords)
                {
                    var list = new List<NewsKeyword>();
                    if (this.DataContent.NewsKeywords.Where(n => n.NewsID == entity.OId && n.KeywordID == keyword.ID).FirstOrDefault() == null)
                    {
                        var nk = new NewsKeyword()
                        {
                            KeywordID = keyword.ID,
                            NewsID = entity.OId,
                            NewsModificationDate = Convert.ToDateTime(entity.ModificationDate)
                        };
                        list.Add(nk);
                        this.DataContent.AddToNewsKeywords(nk);
                    }


                    this.DataContent.SaveChanges();
                    list.ForEach(nkey => this.DataContent.Detach(nkey));
                }
                return true;
            }
            else
            {
                return false;
            }
        }
        public override void Update(News entity)
        {
            var news = this.DataContent.News.Where(n => n.OId == entity.OId).FirstOrDefault();
            news.OId = entity.OId;
            news.EntryId = entity.EntryId;
            news.SummaryHtml = entity.SummaryHtml;
            news.Text = entity.Text;
            news.IsExtracted = entity.IsExtracted;
            news.LanguageID = entity.LanguageID;
            news.Link = entity.Link;
            news.PublishDate = entity.PublishDate;
            news.ModificationDate = entity.ModificationDate;
            news.Publisher = entity.Publisher;
            news.Title = entity.Title;
            this.DataContent.SaveChanges();
            this.DataContent.Detach(news);

        }
        //private News ConvertToNewsEntity(News news)
        //{
        //    var entity = new News();
        //    entity.OId = news.OId;
        //    entity.EntryId = news.EntryId;
        //    entity.Title = news.Title;
        //    entity.ModificationDate = Convert.ToDateTime(news.ModificationDate);
        //    entity.Link = news.Link;
        //    entity.ContentSummery = news.ContentSummery;
        //    entity.ContentText = news.ContentText;
        //    entity.Source = news.Source;

        //    return entity;
        //}
        //private List<News> ConvertToNewsEntityList(IQueryable<News> news)
        //{
        //    var list = new List<News>();
        //    foreach (var n in news)
        //    {
        //        var entity = ConvertToNewsEntity(n);
        //        list.Add(entity);
        //    }
        //    return list;
        //}
        public override News GetById(int OId)
        {
            var news = this.DataContent.News.Where(n => n.OId == OId).FirstOrDefault();
            return news;
        }



        public List<News> GetTodayNews()
        {
            var nextDate = DateTime.Now.AddDays(1).Date;
            var query = this.DataContent.News.Where(n => n.IsDeleted == null || n.IsDeleted == false)
                                            .Where(n => n.ModificationDate >= DateTime.Now.Date)
                                            .Where(n => n.ModificationDate <= nextDate)
                                            .OrderByDescending(n => n.ModificationDate);

            return query.ToList();
        }

        /// <summary>
        /// returns certain Day news
        /// </summary>
        /// <param name="date">Date of the day</param>
        /// <returns></returns>
        public override List<News> GetDayNews(DateTime date)
        {
            var nextDate = date.AddDays(1).Date;
            var query = this.DataContent.News.Where(n => n.IsDeleted == null || n.IsDeleted == false)
                                            .Where(n => n.ModificationDate >= date.Date)
                                            .Where(n => n.ModificationDate <= nextDate)
                                            .OrderByDescending(n => n.ModificationDate);

            return query.ToList();
        }
        /// <summary>
        /// returns certain Day news
        /// </summary>
        /// <param name="date">Date of the day</param>
        /// <returns></returns>
        public override List<News> GetDayNews(DateTime date,Guid userId)
        {
            var keywords = this.DataContent.UserKeywords
                                           .Where(uk => uk.UserId == userId)
                                           .Select(uk => uk.KeywordID)
                                           .ToArray();

            var nextDate = date.AddDays(1).Date;
            var query = this.DataContent.News.Where(n => n.IsDeleted == null || n.IsDeleted == false)
                                            .Where(n => n.ModificationDate >= date.Date)
                                            .Where(n => n.ModificationDate <= nextDate)
                                            .Where(n => n.NewsKeywords.Where(nk => keywords.Contains(nk.KeywordID)).Count() > 0)
                                            .OrderByDescending(n => n.ModificationDate);

            return query.ToList();
        }
        /// <summary>
        /// returns certain Day news
        /// </summary>
        /// <param name="fromdate">Date of the day</param>
        /// <returns></returns>
        public override List<News> GetNews(DateTime fromDate, DateTime toDate)
        {
            var query = this.DataContent.News.Where(n => n.IsDeleted == null || n.IsDeleted == false)
                                            .Where(n => n.ModificationDate >= fromDate.Date)
                                            .Where(n => n.ModificationDate <= toDate.Date)
                                            .OrderByDescending(n => n.ModificationDate);

            return query.ToList();
        }

        public override List<News> GetAll()
        {
            var query = this.DataContent.News
                    .Where(n => n.IsDeleted == null || n.IsDeleted == false)
                    .OrderByDescending(n => n.ModificationDate);

            return query.ToList();
        }



        public override List<News> GetDayNews(DateTime dt, int keywordId)
        {
            if (keywordId <= 0)
                return this.GetDayNews(dt);

            var nextDate = dt.AddDays(1).Date;
            var query = this.DataContent.NewsKeywords.Where(n => n.IsNewsDeleted == null || n.IsNewsDeleted == false)
                                            .Where(n => n.NewsModificationDate >= dt.Date)
                                            .Where(n => n.NewsModificationDate <= nextDate)
                                            .Where(n => n.KeywordID == keywordId)
                                            .Select(n => n.News)
                                            .OrderByDescending(n => n.ModificationDate);
            return query.ToList();

        }
    }
}
